package com.swak.monitor.health.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.swak.App;
import com.swak.Constants;
import com.swak.OS;
import com.swak.registry.NotifyListener;
import com.swak.registry.RegistryService;
import com.swak.registry.URL;
import com.swak.utils.JsonMapper;
import com.swak.utils.Maps;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Service
public class HealthService implements InitializingBean, DisposableBean, NotifyListener {

	private URL url;

	@Autowired(required = false)
	private RegistryService registryService;
	@Autowired
	private App app;

	private final Map<String, Health> cache;

	public HealthService() {
		cache = Maps.newConcurrentMap();
	}

	@Override
	public void notify(List<URL> urls) {
		cache.forEach((k, v) -> v.setOn(false));
		for (URL url : urls) {
			String application = url.getParameter(Constants.Application_KEY);
			String server = url.getParameter(Constants.Server_Key);
			String host = url.getHost();
			cache.compute(application + "." + server, (k, v) -> {
				if (v == null) {
					return new Health().setHost(host).setOn(true);
				}
				return v.setOn(true);
			});
		}
	}

	@Override
	public void destroy() throws Exception {
		if (this.registryService != null) {
			this.registryService.unsubscribe(this.url, this);
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		if (this.registryService != null) {
			Map<String, String> parameters = Maps.newHashMap();
			parameters.put(Constants.Application_KEY, app.getName());
			parameters.put(Constants.Service_Key, Constants.Registry_Health);
			this.url = new URL(Constants.Registry_Monitor_Key, OS.ip(), 0, parameters);
			this.registryService.subscribe(this.url, this);
		}
	}

	/**
	 * 返回健康数据
	 * 
	 * @return
	 */
	public String health() {
		return JsonMapper.toJson(cache);
	}

	/**
	 * 健康指标
	 * 
	 * @author DELL
	 */
	@Getter
	@Setter
	@Accessors(chain = true)
	public class Health {
		private String host;
		private boolean on;
	}
}
